package com.cqu.lpss.service.impl;

import com.cqu.lpss.mapper.*;
import com.cqu.lpss.pojo.*;
import com.cqu.lpss.service.FirstScoringInterface;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FirstScoringImpl implements FirstScoringInterface {
    @Autowired
    ProjectMapper projectMapper;
    @Autowired
    ProfessorsMapper professorsMapper;
    @Autowired
    FirstScoringMapper firstScoringMapper;
    @Autowired
    SecondScoringMapper secondScoringMapper;
    @Autowired
    ScoringCriterionsMapper scoringCriterionsMapper;
    @Autowired
    ScoreDetail1Mapper scoreDetail1Mapper;
    /**
    * @Description:
     * prjStatues:0（初审，交给三级穿甲初审）,proAuth:4 给每个作品分配两个三级权限专家
     * prjStatues：2（初审未通过），
     * prjStatues：1（初审通过，还未进行终审，交给二级专家终审），proAuth:3 给每个作品分配两个二级专家：这个作品最好不是从project中取，而是从finalprojects中取
     * prjStatues：5（终沈通过）
    * @Param:[prjStatues, proAuth]
    * @Return: void
    * @Date: 2024/4/26
    * @Author:liuyawen
    */

    @Override
    public void distribution(Integer prjStatues,Integer proAuth) {
        List<PrjJoinCon> prjJoinCons = projectMapper.select_join(prjStatues);
        List<Professors> professors = professorsMapper.select_All(proAuth);
        List<Integer> classindexs = new ArrayList<>();
        classindexs.add(1);
        classindexs.add(2);
        classindexs.add(3);
        Map<Integer,Set<Integer>> profprj = new HashMap<Integer, Set<Integer>>();
        //过滤处分别属于类别1，2，3的prj和prof
        List<List<PrjJoinCon>> prjJoinConsWithClass =new ArrayList<>();
        List<List<Professors>> professorsWithClass = new ArrayList<>();
        //初审的评审记录
        List<Firstscoring> addForm1 = new ArrayList<>();

        //终审的评审记录
        List<Secondscoring> addForm2 = new ArrayList<>();


        for(int i = 0;i<3;i++){
            int finalI = i;
            List<PrjJoinCon> prjfilterList = prjJoinCons.stream()
                    .filter((PrjJoinCon prj)-> prj.getClassIndex()==classindexs.get(finalI))
                    .collect(Collectors.toList());
            prjJoinConsWithClass.add(prjfilterList);
            List<Professors> proffilterList = professors.stream()
                    .filter((Professors prof)->prof.getProClass() == classindexs.get(finalI))
                    .collect(Collectors.toList());
            professorsWithClass.add(proffilterList);
        }
//        log.info("prjJoinConsWithClass:{}",prjJoinConsWithClass);
//        log.info("professorsWithClass:{}",professorsWithClass);
//        Random random = new Random();
        for (int i = 0; i < prjJoinConsWithClass.size(); i++) {
            List<PrjJoinCon> prjList = prjJoinConsWithClass.get(i);
            List<Professors> profList = professorsWithClass.get(i);


            Integer[] flag = new Integer[profList.size()];
            for(int p=0;p<flag.length;p++){
                flag[p]=0;
            }
            // 随机分配，尽量平均分配
            for (int j = 0;j < prjList.size(); j++) {
                Random random = new Random();
//                List<Professors> tempprofList = new ArrayList<>(profList);

                log.info("flag:{}",flag);
                PrjJoinCon prjJoinCon = prjList.get(j);
                Set<Integer> assignprof = new HashSet<>();
                // 打乱 prjList 的顺序
                while(assignprof.size()<5){
                    int randomNum  = random.nextInt(profList.size())+0;
//                // 分配固定数量的项目
                    int min = (int) Collections.min(Arrays.asList(flag));
                    while(flag[randomNum]>min){
                        randomNum = random.nextInt(profList.size())+0;
                    }
                    int first = assignprof.size();
                    assignprof.add(profList.get(randomNum).getProIndex());
                    if(first<assignprof.size()){
                        flag[randomNum]++;
                        if(prjStatues==0){
                            Firstscoring firstscoring = new Firstscoring();
                            firstscoring.setScoPrjid(prjJoinCon.getPrjIndex());
                            firstscoring.setScoProid(profList.get(randomNum).getProIndex());
                            addForm1.add(firstscoring);
                        }
                        if(prjStatues==1){
                            Secondscoring secondscoring = new Secondscoring();
                            secondscoring.setSco2Prjid(prjJoinCon.getPrjIndex());
                            secondscoring.setSco2Proid(profList.get(randomNum).getProIndex());
                            addForm2.add(secondscoring);
                        }

                    }
                }

//                if (!profList.isEmpty()) { // 如果还有教授，分配第二个
//                    assignprof.add(tempprofList.remove(0).getProIndex());
//                }
//
//
//                // 这里处理分配逻辑，例如保存到新的结构中
//                // ...
                if(assignprof.size()!=0){

                    profprj.put(prjJoinCon.getPrjIndex(),assignprof);
                }

            }
        }

        if(prjStatues==0){
            firstScoringMapper.insert_batch(addForm1);
        }
        if(prjStatues==1){
            secondScoringMapper.insert_batch(addForm2);
        }

    }

    @Override
    public int isEmpty() {
        int ans = firstScoringMapper.isEmpty();
        return ans;
    }
    /**
    * @Description:由proId进行初审的所有作品
    * @Param:[proId]
    * @Return: java.util.List<com.cqu.lpss.pojo.Projects>
    * @Date: 2024/5/8
    * @Author:liuyawen
    */

    @Override
    public List<Projects> prjScoByProId(Integer proId) {
        List<Projects> projects = firstScoringMapper.prjScoByProId(proId);
        return projects;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int modifyScore(List<Scoredetail1> scoredetail1s) {
        int classId = scoredetail1s.get(0).getSdClassid1();
        List<Scoringcriterions> scoringcriterions = scoringCriterionsMapper.findByClass(classId);
        //criterionsId:scWeight
        Map<Integer, Double> criterionIdScWeight = new HashMap<>();
        for(int i=0;i<scoringcriterions.size();i++){
            criterionIdScWeight.put(scoringcriterions.get(i).getScId(),scoringcriterions.get(i).getScWeight());
        }
        double totalscore = 0.0;
        for(int i=0;i<scoredetail1s.size();i++){
            scoredetail1s.get(i).setSdTime1(new Timestamp(System.currentTimeMillis()));
            totalscore+=scoredetail1s.get(i).getSdScore1()*criterionIdScWeight.
                    get(scoredetail1s.get(i).getSdCriterionid1());
        }
        int modifyScoreNum = firstScoringMapper.modifyScore(scoredetail1s.get(0).getSdProid(),
                scoredetail1s.get(0).getSdPrjid(), totalscore, scoredetail1s.get(0).getSdTime1());
        log.info("param:{}",scoredetail1s);
        int recordDetailNum = scoreDetail1Mapper.batch_insertDetail(scoredetail1s);
        int numOfGradeIsNUll = firstScoringMapper.numOfScoreisNull();
        if(numOfGradeIsNUll==0){
            List<Projects> projects = projectMapper.list_All();
            for(int i=0;i<projects.size();i++){
                Projects tempprj = projects.get(i);
                Integer prjIndex = tempprj.getPrjIndex();
                List<Firstscoring> firstscorings = firstScoringMapper.findByprjIndex(prjIndex);
                List<Double> grades = new ArrayList<>();
                for(int j = 0;j<firstscorings.size();j++){
                    grades.add(firstscorings.get(j).getScoGrade());
                }
                Double max = Collections.max(grades);
                Double min = Collections.min(grades);

                for(int j=0;j<grades.size();j++){
                    if(grades.get(j).equals(max)){
                        grades.remove(j);
                        break;
                    }
                }
                for(int j=0;j<grades.size();j++){
                    if(grades.get(j).equals(min)){
                        grades.remove(j);
                        break;
                    }
                }


                // Calculate the average of the remaining numbers
                Double sum = 0.0;
                for (Double grade : grades) {
                    sum += grade;
                }
                log.info("sum:{}",sum);
                Double averageGrade = sum /Double.valueOf(grades.size());
                log.info("averageGrade:{}",averageGrade);
                int ans = projectMapper.modifyFirstGrade(prjIndex,averageGrade);
            }
            projects = projectMapper.list_All();
            // 使用Collections.sort和自定义比较器按prj_score排序
            Collections.sort(projects, Comparator.comparing(Projects::getPrjScore).reversed());

            // 遍历列表，前20个设置prj_state为1，其余为2
            for (int i = 0; i < projects.size(); i++) {
                Integer status = i < 20 ? 1 : 2;
                projects.get(i).setPrjStatus(status);
                int modifystatus = projectMapper.modifyPrjStatus(projects.get(i).getPrjIndex(),status);
            }

        }
        return recordDetailNum*modifyScoreNum;
    }

    @Override
    public List<ChartsData> proUnscoreNum() {
        List<ChartsData> professorUnscoreNums = firstScoringMapper.professorUnscoreNum();
        return professorUnscoreNums;

    }

    @Override
    public int scoreisNull() {
        return firstScoringMapper.scoreisNull();
    }
}
